package ahaha;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class OptimisticUnLock {//演示多线程，乐观锁

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            int num=i%3+1;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        OptimisticUnLock t=new OptimisticUnLock();
                        t.buy(num);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }




    String url = "jdbc:mysql://www.vm.com:3306/test?characterEncoding=utf-8&useSSL=false";
    Connection connection = null;

    public void buy(int num) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        connection = DriverManager.getConnection(url, "root", "root");
        connection.setAutoCommit(false);//不能自动提交事务
        int[] result = getAmount();
        if (result[0] >= num) {//库存足够，可以购买
            try {
                updateAmount(num,result[1]);//减库存
                addOrder(num);//下订单
                connection.commit();
            } catch (Exception e) {
                e.printStackTrace();
                connection.rollback();
                //递归再买
            }

        } else {
            System.out.println("库存不足");
        }
        connection.close();
    }

    public int[] getAmount() throws Exception {
        String amountSql = "SELECT amount,version FROM goods WHERE id=1";
        Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(amountSql);//查询库存
        int[] result = new int[2];
        if (rs.next()) {
            result[0] = rs.getInt(1);
            result[1] = rs.getInt(2);
            System.out.println(Thread.currentThread().getName()+"查询库存");
        }
        rs.close();
        return result;
    }

    public int addOrder(int num) throws Exception {

        Statement statement = connection.createStatement();
        String orderSql = "insert into goods_order(amount,name)values(" + num + ",'" + Thread.currentThread().getName() + "')";
        int res = statement.executeUpdate(orderSql);
        System.out.println(Thread.currentThread().getName()+"添加订单");
        statement.close();
        if (res <= 0) {
            throw new Exception("添加订单失败");
        }

        return res;
    }

    public int updateAmount(int num,int version) throws Exception {

        Statement statement = connection.createStatement();
        String updateSql = "UPDATE goods SET amount=amount-" + num + ",version=version+1 WHERE id=1 and version="+version;
        int res = statement.executeUpdate(updateSql);
        System.out.println(Thread.currentThread().getName()+"更新库存");
        statement.close();
        if (res <= 0) {
            throw new Exception("更新库存失败");
        }
        return res;
    }
}
